package wf.source.hrm.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import wf.source.hrm.client.RedisClient;
import wf.source.hrm.config.RabbitmqConfig;
import wf.source.hrm.domain.Sso;
import wf.source.hrm.domain.VipBase;
import wf.source.hrm.jwt.JwtUtils;
import wf.source.hrm.mapper.SsoMapper;
import wf.source.hrm.mapper.VipBaseMapper;
import wf.source.hrm.service.ISsoService;
import wf.source.hrm.util.*;
import wf.source.hrm.util.encrypt.MD5;

import java.security.PrivateKey;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author wangfang
 * @since 2020-06-30
 */
@Service
public class SsoServiceImpl extends ServiceImpl<SsoMapper, Sso> implements ISsoService {
    @Autowired
    private SsoMapper ssoMapper;

    @Autowired
    private RedisClient redisClient;

    @Autowired
    private VipBaseMapper vipBaseMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public AjaxResult login(Map<String, Object> params) {
        //1 接收参数
        String username = (String) params.get("username"); //username phone email
        String password = (String) params.get("password");
        Integer userType = Integer.valueOf(params.get("userType").toString());
        //2 校验 手机是否被注册 短信验证码
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)
                || userType==null)
            return AjaxResult.me().setSuccess(false).setMessage("请输入相关参数！");
        //判断用户是否存在
        Sso sso = ssoMapper.login(params);
        if (sso == null)
            return AjaxResult.me().setSuccess(false).setMessage("请输入正确用户名或密码！");
        //校验密码是否正确
        String inputPwd = MD5.getMD5(password + sso.getSalt());
        if (!sso.getPassword().equals(inputPwd))
            return AjaxResult.me().setSuccess(false).setMessage("请输入正确用户名或密码！");

        //3 token构造 redis token:jwt
        //3.1 获取私钥
        PrivateKey privateKeyPath = RsaUtils.getPrivateKey(SsoServiceImpl.class.getClassLoader()
                .getResource("hrm_auth_rsa").getFile());
        //3.2 产生jwttoken
        String jwtToken = JwtUtils.generateTokenExpireInMinutes(sso, privateKeyPath, 30);
        String token = UUID.randomUUID().toString();
        //3.3 保存到redis
        Map<String,Object> paramsTmp = new HashMap<>();
        paramsTmp.put("key",token);
        paramsTmp.put("value",jwtToken);
        paramsTmp.put("expire",30*60);
        redisClient.add(paramsTmp);
        //3.4 返回结果
        Map<String,Object> result = new HashMap<>();
        sso.setPassword(null); //前端吧不需要密码
        sso.setSalt(null);
        result.put("sso",sso);
        result.put("token",token);
        return AjaxResult.me().setResultObj(result);
    }

    @Override
    public AjaxResult register(Map<String, Object> params) {
        //把前台传入的参数转为字符串
        String mobile= (String) params.get("mobile");
        String password= (String) params.get("password");
        String smsCode = (String) params.get("smsCode");
        String email = (String) params.get("email");
        //1校验手机号是否已注册 验证码是否正确
        if(StringUtils.isBlank(mobile)||StringUtils.isBlank(password)||StringUtils.isBlank(smsCode)){
            //如果前台没有传递上面的3个参数
            return AjaxResult.me().setSuccess(false).setMessage("请输入有关参数!");
        }
        EntityWrapper<Sso> wrapper=new EntityWrapper<>();
        wrapper.eq("phone",mobile);//手机号
        wrapper.eq("userType", UserType.USERTYPE_VIP);//用户类型
        List<Sso> ssos=ssoMapper.selectList(wrapper);
        if(ssos!=null && ssos.size()>0){
            return AjaxResult.me().setSuccess(false).setMessage("该账户已被注册!");
        }
        //从缓存中获取
        String code=redisClient.get(UserConstants.REGISTER_CODE_PREFIX+mobile);
        //如果缓存中的code为空 或者不等于 前台用户写的短信验证码
        if(StringUtils.isBlank(code)||!(code.split(":")[0].equalsIgnoreCase(smsCode))){
            return AjaxResult.me().setSuccess(false).setMessage("请输入正确的验证码!");
        }

        //首先保存主表信息 t_sso
        Sso sso=new Sso();
        sso.setPhone(mobile);
        sso.setCreateTime(System.currentTimeMillis());
        sso.setUsername(mobile);
        sso.setNickName(StrUtils.getComplexRandomString(4));
        sso.setUserType(UserType.USERTYPE_VIP);
        sso.setSecLevel(0);
        //用户状态 -1未激活 1已激活 2已进行实名认证
        sso.setBitState(2L);
        //随机生成一个32位盐值
        String salt=StrUtils.getComplexRandomString(32);
        //加密后的字符串
        String secretePwd = MD5.getMD5(password + salt);
        sso.setSalt(salt);
        sso.setPassword(secretePwd);
        ssoMapper.insert(sso);
        // 再保存关联表 t_vip_base
        VipBase vipBase=new VipBase();
        vipBase.setCreateTime(System.currentTimeMillis());
        vipBase.setRegTime(System.currentTimeMillis());
        vipBase.setSsoId(sso.getId());
        // 手机0 pc为1 平板 2
        vipBase.setRegChannel(VipBaseConstant.VipBase_RegComputer);
        vipBase.setLevel(0);
        vipBase.setGrowScore(0);//成长值
        vipBaseMapper.insert(vipBase);

        //生成消息
//        "{"+"phone"+":"+mobile,"email"+":"+email+"}"
//        String message ="{"+"phone"+":"+mobile+","+"email"+":"+email+"}";
//        String message = "{\"phone\":\""+mobile+"\",\"email\":\""+email+"\"}";
//        rabbitTemplate.convertAndSend(RabbitmqConfig.EXCHANGE_FANOUT_INFORM,"",message);
//        return AjaxResult.me();
        String jsonSso = JSONObject.toJSONString(sso);
        if (sso.getPhone()!=null) {
            rabbitTemplate.convertAndSend(RabbitmqConfig.EXCHANGE_FANOUT_INFORM,"hrm.send.phone.message",jsonSso);
        }
        if (sso.getEmail() != null) {
            rabbitTemplate.convertAndSend(RabbitmqConfig.EXCHANGE_FANOUT_INFORM,"hrm.send.email.message",jsonSso);
        }
        return AjaxResult.me().setMessage("注册成功");
    }
}
